/*
	GadgetDrive.cpp
	(c)1999 PaleStar Development, Richard Lyle
*/


#include "Debug/Assert.h"
#include "NounShip.h"
#include "GadgetDrive.h"
#include "GameContext.h"

//----------------------------------------------------------------------------

IMPLEMENT_ABSTRACT_FACTORY( GadgetDrive,  NounGadget  ); 
REGISTER_FACTORY_KEY( GadgetDrive, 4099437687301286850 );

BEGIN_ABSTRACT_PROPERTY_LIST( GadgetDrive, NounGadget );
END_PROPERTY_LIST();

GadgetDrive::GadgetDrive()
{
	m_Flags |= FLAG_ACTIVE;
}

//----------------------------------------------------------------------------

void GadgetDrive::setup()
{
	NounGadget::setup();
	m_Flags |= FLAG_ACTIVE;
}

void GadgetDrive::initialize()
{
	NounGadget::initialize();
	m_Flags |= FLAG_ACTIVE;
}

void GadgetDrive::inflictDamage( dword nWhen, Noun * pFrom, int damage, dword type, const Vector3 & direction )
{
	NounShip * pShip = WidgetCast<NounShip>( parent() );
	if ( pShip != NULL )
	{
		// apply the damage to this drive
		NounGadget::inflictDamage( nWhen, pFrom, damage, type, direction );
		// update the ship characteristics and unlock the dynamics
		pShip->updateCharacter();
	}
	else
	{
		// drive not attached to a ship, just call the base class
		NounGadget::inflictDamage( nWhen, pFrom, damage, type, direction );
	}
}

//----------------------------------------------------------------------------

NounGadget::Type GadgetDrive::type() const
{
	return( DRIVE );
}

NounGadget::EnergyClass GadgetDrive::energyClass() const
{
	return ENERGY_CLASS_DRIVES;
}

float GadgetDrive::addThrust() const
{
	return( active() ? thrust() * damageRatioInv() : 0.0f );
}

int GadgetDrive::addMaxEnergy() const
{
	return( maxEnergy() );
}

float GadgetDrive::addSignature() const
{
	return( active() ? ((NounShip *)parent())->velocity() * 0.1f : 0.0f );
}

bool GadgetDrive::usable( Noun * pTarget, bool shift ) const
{
	if ( destroyed() )
		return false;
	return true;
}

bool GadgetDrive::useActive() const
{
	return active();
}

void GadgetDrive::use( dword nWhen, Noun * pTarget, bool shift)
{
	// toggle drive
	setFlags( FLAG_ACTIVE, !active() );

	NounShip * pShip = WidgetCast<NounShip>( parent() );
	if ( pShip != NULL )
		pShip->updateCharacter();
}

int	GadgetDrive::useEnergy( dword nTick, int energy )
{
	if ( active() )
	{
		int generate = damageRatioInv() * this->energy();
		// reduce energy based on velocity
		NounShip * pShip = WidgetCast<NounShip>( parent() );
		if ( pShip != NULL )
		{
			if ( energyFalloff() > 0 && pShip->maxVelocity() > 0.0f )
			{
				float scale = pShip->velocity() / pShip->maxVelocity();
				generate -= (energyFalloff() * scale);
			}
		}

		energy += generate;
	}

	return energy;
}

//----------------------------------------------------------------------------
// EOF


